﻿using ApprovalFlow_WebApi.PlugIn;
using System.Globalization;
using System.Net;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Utility
{
    /// <summary>
    /// http请求接口
    /// </summary>
    public static class HttpRequest
    {
        /// <summary>
        /// 实例化
        /// </summary>
        private static HttpClient _httpClient = new HttpClient() { Timeout = TimeSpan.FromSeconds(20) };

        /// <summary>
        /// 获取api地址--OverallAuth2.0
        /// </summary>
        /// <returns></returns>
        private static string GetApiUrl()
        {
            var config = AppSettingsPlugIn.GetNode<OpenApiConfig>("OpenApiConfig");
            return config.OverallAuthApi;
        }

        /// <summary>
        /// 获取api地址--SingleSignOn 单点登录
        /// </summary>
        /// <returns></returns>
        private static string GetSSOApiUrl()
        {
            var config = AppSettingsPlugIn.GetNode<OpenApiConfig>("OpenApiConfig");
            return config.SingleSignOnApi;
        }

        /// <summary>
        /// get请求
        /// </summary>
        /// <typeparam name="T">泛型</typeparam>
        /// <param name="url">请求地址</param>
        /// <param name="token">请求token</param>
        /// <returns>返回数据</returns>
        public static async Task<HttpRequestModel<T>> GetAsync<T>(string url, string? token = null)
        {
            try
            {
                var configUrl = GetApiUrl();
                url = configUrl + url;
                var request = new HttpRequestMessage(HttpMethod.Get, url);
                if (!string.IsNullOrWhiteSpace(token))
                {
                    request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
                }
                var response = await _httpClient.SendAsync(request);
                return await ProcessResponse<T>(response);
            }
            catch (HttpRequestException ex)
            {
                ExceptionHelper.ThrowBusinessException(string.Format("接口：{0}调用失败；失败原因{1}", url, ex.Message));

                return new HttpRequestModel<T>
                {
                    Success = false,
                    Message = ex.Message,
                    StatusCode = HttpStatusCode.BadRequest
                };
            }
            catch (Exception ex)
            {
                ExceptionHelper.ThrowBusinessException(string.Format("接口：{0}调用失败；失败原因{1}", url, ex.Message));
                return new HttpRequestModel<T>
                {
                    Success = false,
                    Message = ex.Message,
                    StatusCode = HttpStatusCode.BadRequest
                };
            }
        }

        /// <summary>
        /// POST请求
        /// </summary>
        /// <typeparam name="T">泛型</typeparam>
        /// <param name="url">请求地址</param>
        /// <param name="data">请求参数</param>
        /// <param name="token">token</param>
        /// <returns>返回数据</returns>
        public static async Task<HttpRequestModel<T>> PostAsync<T>(string url, object data, string? token = null)
        {
            try
            {
                if (!string.IsNullOrWhiteSpace(token))
                {
                    // 设置请求头
                    _httpClient.DefaultRequestHeaders.Authorization =
                    new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
                    _httpClient.DefaultRequestHeaders.Accept.Add(
                        new MediaTypeWithQualityHeaderValue("application/json"));
                }
                var content = new StringContent(
                      JsonSerializer.Serialize(data),
                      Encoding.UTF8,
                      "application/json");

                var configUrl = GetApiUrl();
                url = configUrl + url;
                var response = await _httpClient.PostAsync(url, content);
                return await ProcessResponse<T>(response);
            }
            catch (HttpRequestException ex)
            {
                ExceptionHelper.ThrowBusinessException(string.Format("接口：{0}调用失败；失败原因{1}", url, ex.Message));
                return new HttpRequestModel<T>
                {
                    Success = false,
                    Message = ex.Message,
                    StatusCode = HttpStatusCode.BadRequest
                };
            }
            catch (Exception ex)
            {
                ExceptionHelper.ThrowBusinessException(string.Format("接口：{0}调用失败；失败原因{1}", url, ex.Message));
                return new HttpRequestModel<T>
                {
                    Success = false,
                    Message = ex.Message,
                    StatusCode = HttpStatusCode.BadRequest
                };
            }
        }

        /// <summary>
        /// POST请求
        /// </summary>
        /// <typeparam name="T">泛型</typeparam>
        /// <param name="url">请求地址</param>
        /// <param name="data">请求参数</param>
        /// <param name="token">token</param>
        /// <returns>返回数据</returns>
        public static async Task<HttpRequestModel<T>> PostLoginAsync<T>(string url, object data, string? token = null)
        {
            try
            {
                if (!string.IsNullOrWhiteSpace(token))
                {
                    // 设置请求头
                    _httpClient.DefaultRequestHeaders.Authorization =
                    new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
                    _httpClient.DefaultRequestHeaders.Accept.Add(
                        new MediaTypeWithQualityHeaderValue("application/json"));
                }
                var content = new StringContent(
                      JsonSerializer.Serialize(data),
                      Encoding.UTF8,
                      "application/json");

                var configUrl = GetSSOApiUrl();
                url = configUrl + url;
                var response = await _httpClient.PostAsync(url, content);
                return await ProcessResponse<T>(response);
            }
            catch (HttpRequestException ex)
            {
                ExceptionHelper.ThrowBusinessException(string.Format("接口：{0}调用失败；失败原因{1}", url, ex.Message));
                return new HttpRequestModel<T>
                {
                    Success = false,
                    Message = ex.Message,
                    StatusCode = HttpStatusCode.BadRequest
                };
            }
            catch (Exception ex)
            {
                ExceptionHelper.ThrowBusinessException(string.Format("接口：{0}调用失败；失败原因{1}", url, ex.Message));
                return new HttpRequestModel<T>
                {
                    Success = false,
                    Message = ex.Message,
                    StatusCode = HttpStatusCode.BadRequest
                };
            }
        }

        /// <summary>
        /// 统一响应处理
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="response"></param>
        /// <returns></returns>
        private static async Task<HttpRequestModel<T>> ProcessResponse<T>(HttpResponseMessage response)
        {
            var result = new HttpRequestModel<T>
            {
                StatusCode = response.StatusCode,
                Success = response.IsSuccessStatusCode,
            };

            var content = await response.Content.ReadAsStringAsync();

            if (response.IsSuccessStatusCode && !string.IsNullOrEmpty(content))
            {
                result.Data = JsonSerializer.Deserialize<ReceiveStatus<T>>(content, JsonSerializerOptions()).data;
            }
            else
            {
                result.Message = content;
            }

            return result;
        }

        /// <summary>
        /// 自定义json解析属性
        /// </summary>
        /// <returns></returns>
        private static JsonSerializerOptions JsonSerializerOptions()
        {

            var options = new JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true,
                Converters = { new DatetimeJsonConverter() }
            };
            return options;
        }
    }

    /// <summary>
    /// 请求返回模型
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class HttpRequestModel<T>
    {
        /// <summary>
        /// 结果
        /// </summary>
        public T? Data { get; set; }

        /// <summary>
        /// 状态码
        /// </summary>
        public HttpStatusCode StatusCode { get; set; }

        /// <summary>
        /// 是否成功
        /// </summary>
        public bool Success { get; set; }

        /// <summary>
        /// 返回消息
        /// </summary>
        public string Message { get; set; } = string.Empty;
    }

    /// <summary>
    /// overallAuth系统配置
    /// </summary>
    public class OpenApiConfig
    {
        /// <summary>
        /// overallAuth Api地址
        /// </summary>
        public string OverallAuthApi { get; set; } = string.Empty;

        /// <summary>
        /// SingleSignOn Api地址
        /// </summary>
        public string SingleSignOnApi { get; set; } = string.Empty;
    }
}
